import wsgiref.handlers
from google.appengine.ext import webapp
from google.appengine.ext import db

import string
import StringIO

from pixeltoy import colorlib
from pixeltoy import model
from pixeltoy import tracker
from pixeltoy import header

page_template = string.Template('''
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<link rel="stylesheet" type="text/css" href="files/site.css"/>
<script type="text/javascript" src="files/jquery-1.2.3.min.js"></script>
<script type="text/javascript" src="files/pixeltoy.js"></script>
<style type="text/css">
$colors_css
</style>
<head>
<body>
$header

<div id='border'>
<div id='title'>PixelToy!</div>
<table><tr><td>
<table id='pixels'>
$pixel_rows
</table>

</td><td id='rightside'>
<table id='palette'>
$palette
</table>
</td></tr>

<tr><td>
<form action="take_snapshot" method="post" id="takesnapshot">
  <input type="submit" value="Take Snapshot">
  <a href="/gallery">See Gallery</a>
</form>
</td></tr>

</table>
</div>

$tracker
</body>
</html>
''')


color_css_template = string.Template(
    '.$colorclass { background-color: #$colorname; border-color: #$colorname; }\n')


pixel_template = string.Template('<td id="_${x}.${y}" class="$colorclass"></td>')


color_template = string.Template('''
<td id='$colorclass' class="$colorclass$selected"></td>
''')


def get_color_class(color_index):
  return "c%s" % color_index


def make_pixel_rows(pixel_record):
  pixel_it = iter(pixel_record.pixels)

  out = StringIO.StringIO()
  for y in range(0, pixel_record.height):
    out.write("<tr>")
    for x in range(0, pixel_record.width):
      color_index = ord(pixel_it.next())
      out.write(pixel_template.substitute(x=x, y=y,
                                          colorclass=get_color_class(color_index)))
    out.write("</tr>\n")
  return out.getvalue()


class MainPage(webapp.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'text/html'
    self.response.out.write(self.make_page(host=self.request.environ['SERVER_NAME']))

  def make_page(self, host):
    grid = model.get_pixels()
    return page_template.substitute(
        header = header.make_header_html('/'),
        colors_css = self.make_colors_css(grid),
        pixel_rows = make_pixel_rows(grid),
        palette = self.make_palette(grid),
        tracker = tracker.make_tracker(host))

  def make_colors_css(self, grid):
    out = StringIO.StringIO()
    for i in xrange(0,len(grid.colors)):
      out.write(color_css_template.substitute(colorclass = get_color_class(i),
                                              colorname = grid.colors[i]))
    return out.getvalue()

  def make_palette(self, grid):
    out = StringIO.StringIO()
    palette_width = colorlib.palette_size[0]
    for index in xrange(0, len(grid.colors)):

      if index % palette_width == 0:
        out.write("<tr>")

      colorclass = 'c%d' % index
      if index == colorlib.starting_color:
        selected = ' selected-color'
      else:
        selected = ''
      out.write(color_template.substitute(colorclass = colorclass, selected = selected))

      if index % palette_width == palette_width - 1:
        out.write("</tr>")

    if len(grid.colors) % palette_width != 0:
      out.write("</tr>")

    return out.getvalue()


class ApplyStroke(webapp.RequestHandler):
  def post(self):
    def transaction(data):
      pixels = model.get_pixels()
      pixels.apply_stroke(data)
      pixels.put()
      return pixels
    pixels = db.run_in_transaction(transaction, self.request.get('data'))
    self.response.headers['Content-Type'] = 'text/plain'
    out = self.response.out.write(make_pixel_rows(pixels))


class GetPixels(webapp.RequestHandler):
  def get(self):
    pixels = model.get_pixels()
    self.response.headers['Content-Type'] = 'text/plain'
    out = self.response.out.write(make_pixel_rows(pixels))


class TakeSnapshot(webapp.RequestHandler):
  def post(self):
    pixels = model.get_pixels()
    pixels.to_snapshot().put()
    self.redirect("/gallery")


def main():
  application = webapp.WSGIApplication([('/', MainPage),
                                        ('/stroke', ApplyStroke),
                                        ('/pixels', GetPixels),
                                        ('/take_snapshot', TakeSnapshot)],
                                       debug=True)
  wsgiref.handlers.CGIHandler().run(application)


if __name__ == "__main__":
  main()
